package com.bu.web;

import java.net.URI;
import java.net.URISyntaxException;

import javax.jdo.PersistenceManager;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import com.bu.model.Problem;
import com.bu.model.Topic;
import com.bu.service.PMF;
import com.google.appengine.api.datastore.Text;
import com.sun.jersey.api.view.Viewable;

/**
 * @author xueqiang.mi
 * @since 2011-2-22
 */
@Path("/problem")
@Component
@Scope(BeanDefinition.SCOPE_SINGLETON)
public class ProblemResource extends BaseResource {

	@GET
	@Path("crtOrEdit")
	public Response crtOrEdit(@QueryParam("id") Long id, @QueryParam("back") String back, @Context HttpServletRequest request) {
		HttpSession session = request.getSession();
		String queryString = request.getQueryString();
		queryString = StringUtils.substringAfter(queryString, "&back=");
		session.setAttribute("back", queryString);

		if (null == id) {
			return Response.ok(new Viewable("problem", null)).build();
		}
		Problem p = problemService.get(id);
		return Response.ok(new Viewable("problem", p)).build();
	}

	@GET
	@Path("delete")
	public Response delete(@QueryParam("id") Long id, @Context HttpServletRequest request) throws URISyntaxException {
		problemService.delete(id);

		HttpSession session = request.getSession();
		String back = session.getAttribute("back").toString();
		if (null == back || "null".equals(back)) {
			return Response.seeOther(new URI("/index")).build();
		}
		return Response.seeOther(new URI("/search?" + back)).build();
	}

	@POST
	@Path("save")
	@Produces("text/plain")
	public Response save(@FormParam("id") Long id, @FormParam("topics") String topics, @FormParam("problem") String problem,
			@FormParam("solution") String solution, @FormParam("source") String source, @FormParam("difficulty") float difficulty,
			@FormParam("note") String note, @Context HttpServletRequest request) throws URISyntaxException {
		Problem p = null;
		if (id == null || id == 0) { // create a new problem
			p = new Problem();
			p.setTopics(topics);
			p.setProblem(new Text(problem));
			p.setSolution(new Text(solution));
			p.setSource(source);
			p.setDifficulty(difficulty);
			p.setNote(new Text(note));
			problemService.add(p);
		} else { // update a problem
			PersistenceManager pm = PMF.get();
			try {
				p = pm.getObjectById(Problem.class, id);
				if (!p.getTopics().equals(topics)) {// update topics
					String[] array = p.getTopics().split(",");
					for (String str : array) {
						str = str.trim();
						if (null == str || "".equals(str)) {
							continue;
						}
						Topic t = pm.getObjectById(Topic.class, str);
						t.getProblems().remove(p.getId());
					}

					array = topics.split(",");
					for (int i = 0; i < array.length; i++) {
						String str = array[i].trim();
						if (null == str || "".equals(str)) {
							continue;
						}
						Topic t = null;
						try {
							t = pm.getObjectById(Topic.class, str);
						} catch (Exception e) {
							// Ignore
						}
						if (t == null) {
							t = new Topic(str, i);
						}
						if (t.getLevel() == 0) { // add sub topic when processing root topic
							for (int j = 1; j < array.length; j++) {
								t.getChildren().add(array[j].trim());
							}
						}
						t.getProblems().add(p.getId());
						pm.makePersistent(t);
					}
				}
				if (p != null) {
					p.setTopics(topics);
					p.setProblem(new Text(problem));
					p.setSolution(new Text(solution));
					p.setSource(source);
					p.setDifficulty(difficulty);
					p.setNote(new Text(note));
				}
			} finally {
				pm.close();
			}
		}
		HttpSession session = request.getSession();
		String back = session.getAttribute("back").toString();
		if (null == back || "null".equals(back)) {
			return Response.seeOther(new URI("/index")).build();
		}
		return Response.seeOther(new URI("/search?" + back)).build();
	}
}
